package controller;

import java.sql.*;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.ResourceBundle;
import javax.servlet.*;
import javax.servlet.http.*;
import model.User;
import model.Message;
import model.UserState;
import utilities.CookiesMgr;
import utilities.ParametersValidator;
import webSiteDataStore.UserData;
import utilities.SafeSessionAccess;

public class SignIn extends HttpServlet
{
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, SQLException
    {
        ParametersValidator.ValidateProgrammerParameters(request, "mode");

        HttpSession session = request.getSession(true);
        SafeSessionAccess.setAttribute( session, "appTitle", "Gamers' Web");
        SafeSessionAccess.setAttribute( session, "emailId", "gamersweb");
        SafeSessionAccess.setAttribute( session, "emailDomain", "live.com");
        SafeSessionAccess.setAttribute( session, "presentationMedium", "desktop");

        // TODO: this should be an application attribute, not a session attribute.
        ResourceBundle resources = ResourceBundle.getBundle("controller.StringResources");        
        SafeSessionAccess.setAttribute( session, "stringResources", resources);

        String userName = "";
        boolean authenticated = false;
        String mode = request.getParameter("mode");
        if (mode.equals("dosignin"))
        {
            userName = request.getParameter("userName");
            boolean notEnoughData = !ParametersValidator.ValidateUserParameters(request, "userName", "password");
            if (!notEnoughData)
            {
                int password = request.getParameter("password").hashCode();
                User user = new User(userName, password);
                int userId = UserData.authenticateUser(user);
                if (userId != -1)
                {
                    authenticated = true;
                    user.setUserId(userId);
                    user.setState(UserState.SIGNEDIN);
                    UserData.loadProfile(user);
                    SafeSessionAccess.setAttribute(session, "user", user);

                    Cookie emailCookie = new Cookie("userName", user.getUserName());
                    emailCookie.setPath("/");
                    emailCookie.setMaxAge(60*60*24*365);
                    response.addCookie(emailCookie);
                }
            }

            if (!authenticated)
            {            
                Message displayMessage = new Message(resources.getString("TITLE_AUTH_FAILURE"), 
                                             resources.getString(notEnoughData ? "TEXT_DATA_MISSING" : "TEXT_AUTH_FAILURE"));

                request.setAttribute("displayMessage", displayMessage);
                mode = "signIn";
                response.setStatus(HttpServletResponse.SC_ACCEPTED); // TODO: created a shared user defined error code.
            }
        }
        else
        {
            userName = CookiesMgr.getCookieValue(request, "userName");
        }

        request.setAttribute("userName", userName);
        request.setAttribute("presentationMedium", "desktop"); // This servlet never access by mobile.       
        request.setAttribute("pageTitle", "Sign in");
        String nextPage = authenticated ? nextPage = "/OtherProfiles" : "/signin.jsp?mode=" + mode;
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextPage);
        dispatcher.forward(request, response);
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (SQLException ex) {
            Logger.getLogger(SignIn.class.getName()).log(Level.SEVERE, null, ex);
        }
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (SQLException ex) {
            Logger.getLogger(SignIn.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}